package com.atguigu.hdfs;

import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.*;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;

import java.net.URI;
import java.util.Arrays;

import static java.lang.System.*;

/**
 * @description: hdfs操作api集合
 * 获取客户端对象
 * 执行相关操作命令
 * 关闭资源
 * @create: 2019-12-01 23:18
 * @author: baojinlong
 **/
public class HDFSClient {
    private FileSystem fileSystem;

    public static void main(String[] args) throws Exception {
        // 1.获取对象
        Configuration conf = new Configuration();
        // 1.1设置namenode相关属性,设置运行用户-DHADOOP_USER_NAME=atguigu
        conf.set("fs.defaultFS", "hdfs://hadoop102:9000");

        //FileSystem fileSystem = FileSystem.get(conf);
        // 或者设置不需要指定用户
        FileSystem fileSystem = FileSystem.get(new URI("hdfs://hadoop102:9000"), conf, "atguigu");
        // 2.创建一个文件夹
        fileSystem.mkdirs(new Path("/0705/dashenban"));
        // 3.关闭资源
        fileSystem.close();
        out.println("over ok");
    }

    @Before
    public void initProcess() throws Exception {
        // 连接的集群nn地址
        URI uri = new URI("hdfs://hadoop102:8020");
        // 创建一个配置文件
        Configuration configuration = new Configuration();
        configuration.set("dfs.replication", "2");
        // 获取到客户端对象,这里如果不设置用户则出现权限问题
        fileSystem = FileSystem.get(uri, configuration, "atguigu");
    }

    /**
     * 创建文件夹
     */
    @Test
    public void testMkDir() throws Exception {
        // 创建一个文件夹
        boolean mkResult = fileSystem.mkdirs(new Path("xiyou/huaguoshang"));
        out.println("创建结果为" + mkResult);
    }

    /**
     * 上传文件配置参数优先级:hdsf-default.xml<hdfs-site.xml<在项目资源目录下配置文件<代码中配置configuration
     *
     * @throws Exception
     */
    @Test
    public void testUploadFile() throws Exception {
        // 表示删除元数据  是否允许覆盖 原数据路径 目的地路径
        fileSystem.copyFromLocalFile(false, false, new Path("d:/sunwukong.txt"), new Path("hdfs://hadoop102/xiyou/huaguoshan"));
    }

    @Test
    public void testDownload() throws Exception {
        // 原文件是否删除 原文件的路径 目标地址路径 是否使用crc加密
        fileSystem.copyToLocalFile(false, new Path("hdfs://hadoop102/xiyou/huaguoshan"), new Path("d:/"), false);
    }

    @Test
    public void testDelete() throws Exception {
        // 删除路径 是否递归删除
        fileSystem.delete(new Path("/jdk-8u212-linx-64.tar.gz"), false);
        // 删除空目录
        fileSystem.delete(new Path("/xiyou"), false);
        // 删除非空目录,需要递归删除true
        fileSystem.delete(new Path("/jinguo"), true);
    }

    @Test
    public void testMove() throws Exception {
        // rename file
        boolean rename = fileSystem.rename(new Path("/input/word.tx"), new Path("/input/ss.txt"));
        out.println("rename" + rename);
        // move and rename file
        fileSystem.rename(new Path("/input/ss.txt"), new Path("/cls.txt"));
        // rename directory
        fileSystem.rename(new Path("/input"), new Path("/output"));
    }

    @Test
    public void testFileDetail() throws Exception {
        RemoteIterator<LocatedFileStatus> locatedFileStatusRemoteIterator = fileSystem.listFiles(new Path("/"), true);
        while (locatedFileStatusRemoteIterator.hasNext()) {
            LocatedFileStatus locatedFileStatus = locatedFileStatusRemoteIterator.next();
            out.println(locatedFileStatus.getPath());
            out.println(locatedFileStatus.getPermission());
            out.println(locatedFileStatus.getGroup());
            out.println(locatedFileStatus.getLen());
            out.println(locatedFileStatus.getModificationTime());
            out.println(locatedFileStatus.getReplication());
            out.println(locatedFileStatus.getBlockSize());
            out.println(locatedFileStatus.getPath().getName());
            // retrieve block info
            BlockLocation[] blockLocations = locatedFileStatus.getBlockLocations();
            out.println(Arrays.toString(blockLocations));
        }
    }

    @Test
    public void testFileStatus() throws Exception {
        FileStatus[] listStatus = fileSystem.listStatus(new Path("/"));
        for (FileStatus status : listStatus) {
            String name = status.getPath().getName();
            if (status.isFile()) {
                out.println("file" + name);
            } else {
                out.println("file directory" + name);
            }
        }

    }

    @After
    public void endProcess() throws Exception {
        fileSystem.close();
    }

}
